
/***************************************************************************
 *   Copyright (C) 1997 to 2004 by Jonathan Duddington                     *
 *   email: jonsd@users.sourceforge.net                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write see:                           *
 *               <http://www.gnu.org/licenses/>.                           *
 ***************************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#include "bbc.h"
#include "dbox.h"
#include "menu.h"
#include "werr.h"
#include "wimp.h"
#include "template.h"
#include "os.h"
#include "print.h"
#include "flex.h"

#include "narc.h"
#include "hdrs.h"

#ifdef MemCheck
#include "MemCheck:Flex.h"
#endif


extern char *de_tab_text(char *p,int n_chars);
extern char *get_current_date_string(int *date_enc);
extern char *decode_date(int date,int timeflag);


extern int print_font;
extern int print_line_height;
extern int scale_x;
extern int scale_y;
extern int margin_l;
extern OPTIONS options;
extern int dbox_menu_field;





void xlog(char *string, int x)
/****************************/
{
	FILE *f;
	f = fopen_pluto("Log","a");
	if(f!= NULL)
	{
		fprintf(f,"%s  %d\n",string,x);
		fclose(f);
	}
}





/*************************************************************/
/*                        PRINTING                           */
/*************************************************************/
int  print_job = -1;
static int  print_expect_ack = 0;
static char *print_tempfile;
static char *print_from_to[] = {"From:","To:  "};


static void print_abort(int print_job, char *mesg)
/*****************************************/
{
	if(print_job < 0)
		return;

	visdelay2_end();

	print_abortjob(print_job);

	if(mesg != NULL)
		werr(FALSE,mesg);


	os_swi2(0x0d, 0, print_job);  /* OS_Find,  close */

	print_job = -1;
}   /* end of print_abort */



int print_datasaveack(wimp_eventdata *d)
/**************************************/
/* Called from wimp module */
{
	wimp_msgstr *m;

	if(print_expect_ack == 0)
		return(FALSE);

	m = &d->msg;

	m->hdr.action = wimp_MDATALOAD;

	/* rename the temp file to where printers wants it */
	file_move(print_tempfile,m->data.dataload.name);
	wimp_sendmessage(wimp_ESEND,m,m->hdr.task);

	print_expect_ack = 0;
	return(TRUE);
}   /* end of print_datasaveack */



static void print_text_simple(TEXTR *t,CARD_EXPANDED *cardex, int from_to,char *title, char*destn, char *date, int selection)
/*****************************************************************************************************/
/* write characters to the printer stream */
{
	FILE *f;
	int  length;
	int  i;
	wimp_msgstr m;
	char *fname;
	int  start, end;
	int  line;
	int  line_start;
	OPTIONS_MAILBOX *mbox;

	fname = get_temp_fname();
	f = fopen_werr(fname,"w",NULL);
	if(f == NULL)
	{
		return;
	}

	print_tempfile = fname;

	if(options.print_options & SAVE_SHORTHDR)
	{
		if(cardex->user > 0)
		{
			mbox = &options.mailbox[cardex->user-1];
			fprintf(f,"%s      %s <%s>\n",print_from_to[from_to ^ 1],mbox->full_name,mbox->email_addr);
		}
		fprintf(f,"%s      %s\nSubject:   %s\nDate:      %s\n\n",
				print_from_to[from_to],destn,title,date);
	}

	/* write out the text to the file */
	start = t->text_start;
	end = t->text_body_end;

	if(selection)
	{
		start = t->region_start;
		end = t->region_end;
	}
	length = end - start;

	if(options.print_options & SAVE_REMOVESIG)
	{
		i = text_find_sig(t->text_base+start,length);
		if(i > 0)
			length = i;
	}

	/* find line number for start of selected text */
	line_start = index_to_linestart(t,start,&line);

	for(; start < end; line++)
	{
		i = t->line_tab[line];
		while(start > line_start)
		{
			/* if we're starting part way through a line */
			fputc(' ',f);
			i--;
			line_start++;
		}

		if((start + i) > end)
			i = end - start;  /* in case we end part way through a line */

		fwrite(&t->text_base[start],i,1,f);
		start = line_start + i;
		line_start = start;
		if(t->text_base[start-1] != '\n')
			fputc('\n',f);   /* terminate line with NL if not already there */
	}

	/* get length of print file */
	fclose(f);

	length = get_filelength(fname);

	/* send PrintSave message */
	m.hdr.size = (44 + strlen(fname) + 4) & ~3;   /* string + zero terminator */
	m.hdr.your_ref = 0;
	m.hdr.action = 0x80142;   /* Message_PrintSave */
	m.data.dataload.w = 0;
	m.data.dataload.i = 0;
	m.data.dataload.x = 0;
	m.data.dataload.y = 0;
	m.data.dataload.size = length;
	m.data.dataload.type = 0xfff;   /* text file */
	strcpy(m.data.dataload.name,fname);

	wimp_sendmessage(wimp_ESEND,&m,0);
	print_expect_ack = 1;  /* indicate that we are expecting a datasaveack from printers */
}   /* end of print_text_simple */



static void print_line(char *string, int x, int y)
/*****************************************/
{
	os_regset regs;

	regs.r[0] = print_font;
	regs.r[1] = (int)string;
	regs.r[2] = 0x180;
	regs.r[3] = x;
	regs.r[4] = y * scale_y;
	regs.r[5] = 0;
	regs.r[6] = 0;
	regs.r[7] = strlen(string);

	os_swi(0x40086, &regs);    /* Font_Paint */
}   /* end of print_line */



static void print_text(TEXTR *t,CARD_EXPANDED *cardex, int from_to,char *title,char *destn,char *date, int print_font, int selection)
/*********************************************************************************************/
/* Print the currently loaded text */
{
	static int  prev_print_job;
	int  paper_depth;
	int  paper_depth2;
	int  paper_width;
	int  page_start_line;
	int  page_end_line;
	int  last_line_y;
	int  page=0;
	int  more;
	int  ident;
	int  line;
	int  y;
	int  index;
	int  index_end;
	int  index_start;
	int  n_lines;
	int  end_flag;
	int  height;
	char *p;
	char *p2;
	int  x;
	int  save_c;
	int  n_chars;
	OPTIONS_MAILBOX *mbox;
	int  short_header_flag = 0;
	int  header_offset = 0;
	int  header_lines = 0;
	int  bottom_margin = 60;
	char buf[200];

	os_error *error;
	print_infostr print_inf;
	print_box box;             /* dimensions of page */
	print_box rectangle;
	print_transmatstr matrix;
	print_positionstr position;
	print_pagesizestr pagesize;

	int  pad;
	os_regset regs;
	static int coord_block[8] = {0,0, 0,0, 0,0, 0,0};

	error = print_info(&print_inf);
	if(error)
	{
		if(error->errnum == 486)
			werr(0,"Printer Driver module is not loaded");
		else
			werr(FALSE,error->errmess);
		return;
	}

	if(print_font < 0)
	{
		/* print as plain text file */
		print_text_simple(t,cardex,from_to,title,destn,date,selection);
		return;
	}

	print_pagesize(&pagesize);
	paper_depth = pagesize.bbox.y1 - pagesize.bbox.y0;
	paper_width = pagesize.bbox.x1 - pagesize.bbox.x0;

	matrix.xy = 0x0;
	matrix.yx = 0x0;
	matrix.xx = 0x10000;
	matrix.yy = 0x10000;

	/* OS_Find,  create file */
	error = os_swi3r(0x2000d, 0x80, (int)"printer:", 0, &print_job, NULL, NULL);
	if(error)   {
		werr(FALSE,error->errmess);
		return;
	}

	error = os_swi2r(0x80145+os_X,print_job,0,&prev_print_job,NULL);  /* PDriver_SelectJob */
	if(error)   {
		print_abort(print_job,error->errmess);
		return;
	};

	if((print_font > 0) && (print_inf.features & 0x20000000))
	{
		/* declare font list */
		os_swi3(0x80155,print_font,0,0);   /* PDriver_DeclareFont */
		os_swi3(0x80155,0,0,0);        /* end of font list */
	}

	visdelay2_begin();

	error=0;
	if(print_font > 0)
	{
		error = os_swi4(0x4074f+os_X,print_font,0xffffff00,0,14);  /* ColourTrans_SetFonTColours */
	}
	else
		set_colour(BLACK,0,0);

	position.dx = 0;
	position.dy = 0;
	paper_depth2 = paper_depth / scale_y;

	index_end = t->text_length;
	if(t->attachments)
		index_end = t->attach[0].displ;

	index_start = t->text_start;

	n_lines = t->n_lines;
	page_start_line = 0;
	page_end_line = 0;
	last_line_y = line_to_warea(n_lines-1,print_line_height);
	last_line_y -= print_line_height;

	if(selection)
	{
		/* this doesn't work properly */
		index_start = t->region_start;
		index_end = t->region_end;
		index_to_linestart(t,index_start,&page_start_line);
	}

	if(options.print_options & SAVE_SHORTHDR)
	{
		short_header_flag = 1;
	}

	if(options.print_options & SAVE_REMOVESIG)
	{
		y = text_find_sig(t->text_base+index_start,index_end-index_start);
		if(y > 0)
			index_end = index_start + y;
	}


	end_flag = 0;
	while((page_start_line < n_lines) && (end_flag == 0))
	{
		/* for each page to print */
		page++;
		ident = page;

		y = 0;

		box.y1 = line_to_warea(page_start_line,print_line_height) - header_offset + print_line_height;
		box.y0 = box.y1 - paper_depth2;
		box.x0 = 0;
		box.x1 = paper_width/scale_x;

		t->n_lines += 0x4000;  /* don't restrict page_end_line to n_lines, allow for header */
		page_end_line = warea_to_line(t,box.y0+header_offset+bottom_margin,&y,NULL,print_line_height);

		t->n_lines -= 0x4000;

		if((y - print_line_height) <= (box.y0 + bottom_margin))
			page_end_line--;

		position.dy = 0;

#ifdef deleted
		y = last_line_y - box.y0;
		if(y > 0)
		{
			box.y0 = last_line_y;
			position.dy = y * scale_y;
		}
#endif

		error = print_giverectangle(ident,&box,&matrix,&position,(int)0xffffff00);
		if(error)   {
			print_abort(print_job,error->errmess);
			return;
		};

		error = print_drawpage(1,page,NULL,&rectangle,&more,&ident);
		if(error)   {
			print_abort(print_job,error->errmess);
			return;
		};

		while(more)
		{
			/* plot to printer */
			line = warea_to_line(t,rectangle.y1+header_offset,&y,&index,print_line_height);
			y -= header_offset;

			visdelay2_percent((100*index)/(t->text_length));
			pad = 0;
			x = pagesize.bbox.x0 + (margin_l * scale_x);
			height = print_line_height;

			if(short_header_flag)
			{
				short_header_flag = 0;

				header_lines=0;
				if(cardex->user > 0)
				{
					mbox = &options.mailbox[cardex->user-1];
					sprintf(buf,"%s      %s <%s>",print_from_to[from_to ^ 1],mbox->full_name,mbox->email_addr);
					print_line(buf,x,y);
					header_lines=1;
				}

				sprintf(buf,"%s      %s",print_from_to[from_to],destn);
				print_line(buf,x,y - print_line_height*header_lines);

				sprintf(buf,"Subject:   %s",title);
				print_line(buf,x,y - print_line_height*(header_lines+1));

				sprintf(buf,"Date:      %s",date);
				print_line(buf,x,y - print_line_height*(header_lines+2));

				header_offset = (print_line_height*(header_lines+4));
				header_lines += 4;
				y -= header_offset;
				page_end_line -= header_lines;
			}

			while(((y+height) > rectangle.y0) && (end_flag == 0))
			{
				if(index < index_start)
					index = index_start;

				if((index >= index_end) || (line > page_end_line))
				{
					/*               end_flag = 1; */
					break;
				}

				p = &t->text_base[index];
				n_chars = t->line_tab[line];
				p = de_tab_text(p,n_chars);

				p2 = strchr(p,'\n');
				if(p2 != NULL)
				{
					n_chars = p2 - p;
				}
				regs.r[0] = print_font;
				regs.r[1] = (int)p;
				regs.r[2] = 0x180;
				regs.r[3] = x;
				regs.r[4] = y * scale_y;
				regs.r[5] = 0;
				regs.r[6] = 0;
				regs.r[7] = n_chars;   /*******/

				if(pad > 0)
				{
					regs.r[2] = 0x1a0;
					coord_block[0] = pad;
					regs.r[5] = (int)coord_block;
				}

				if(line >= page_start_line)
				{
					save_c = p[n_chars];
					p[n_chars] = 0;            /* terminator */
					os_swi(0x40086, &regs);    /* Font_Paint */
					p[n_chars] = save_c;
				}

				y -= print_line_height;
				index += t->line_tab[line];
				line++;
				height = print_line_height;

			}

			error = print_getrectangle(&rectangle, &more, &ident);
			if(error)   {
				print_abort(print_job,error->errmess);
				return;
			}
		}

		/* next page */
		page_start_line = page_end_line + 1;
	}

	visdelay2_end();

	os_swi1(0x80148+os_X,print_job);   /* PDriver_Endjob */
	os_swi2(0x0d, 0, print_job);       /* OS_Find,  close */
	print_job = -1;

#ifdef deleted
	error = os_swi2r(0x80145+os_X,prev_print_job,0,NULL,NULL);  /* PDriver_SelectJob */
#endif

}   /* end of print_text */




static BOOL print_raw_handler(dbox d, void *event, void *handle)
/*******************************************************/
{
	char c;
	wimp_eventstr *e = event;

	switch(e->e)
	{
	case wimp_EKEY:
		c = e->data.key.chcode;
		if(c == 0x1b)
		{
			print_abort(print_job,"Print Cancelled");
		}
	}
	return(FALSE);
}   /* end of print_raw_handler */




void print_text_dialog(TEXTR *t,CARD_EXPANDED *cardex, int from_menu)
/*******************************************************************/
{
	dbox db;
	int  field;
	int  font;
	int from_to;
	int  selection;
	char title[128];
	char destn[128];
	char date[40];


	db = dbox_new("Printquery");
	dbox_raw_eventhandler(db,print_raw_handler,NULL);

	dbox_setnumeric(db,1,(options.print_options & SAVE_SHORTHDR) ? 1:0);   /* short header */
	dbox_setnumeric(db,2,(options.print_options & SAVE_REMOVESIG) ? 1:0);   /* remove sig */
	dbox_setnumeric(db,4,(options.print_options & PRINT_SYSTEM_FONT) ? 1:0);   /* remove sig */
	if(print_font < 0)
		dbox_setnumeric(db,4,1);
	if(t->region_end > t->region_start)
		dbox_setnumeric(db,5,1);   /* "Selection" */
	dbox_show(db);

	if(!from_menu)
		set_dbox_at_pointer(db);

	field = dbox_fillin(db);
	if(field == 0)
	{
		options.print_options = 0;
		if(dbox_getnumeric(db,1))
			options.print_options = SAVE_SHORTHDR;
		if(dbox_getnumeric(db,2))
			options.print_options |= SAVE_REMOVESIG;

		font = print_font;
		if(dbox_getnumeric(db,4))
		{
			font = -1;   /* use printer's text font */
			options.print_options |= PRINT_SYSTEM_FONT;
		}
		options_save();

		selection = dbox_getnumeric(db,5);

		from_to = 1;
		if(t->text_type > X_VIEW2)
		{
			/* read title and destination from dbox */
			dbox_getfield(t->dbox_card,8,title,sizeof(title));
			dbox_getfield(t->dbox_card,9,destn,sizeof(destn));
			strcpy(date,get_current_date_string(NULL));
		}
		else
		{
			strcpy(title,cardex->title);
			strcpy(destn,cardex->author);
			strcpy(date,decode_date(cardex->date,4));

			if((cardex->status_other & STATUS_BIT_OG) == 0)
				from_to = 0;
		}
		dbox_dispose(&db);

		if(t->region_end <= t->region_start)
			selection = 0;

#ifdef deleted
		if((font >= 0) && (selection != 0))
		{
			werr(0,"'Selection' is not implemented for outline fonts");
			return;
		}
#endif

		print_text(t,cardex,from_to,title,destn,date,font,selection);
	}
	else
	{
		if(print_job > 0)
			print_abort(print_job,"Print Cancelled 2");
		dbox_dispose(&db);
	}

}   /* end of print_text_dialog */





void terminate_print()
/********************/
{
	print_abort(print_job,NULL);
}   /* end of terminate_print */

